﻿using Core.Tools.IOC;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Core.Tools.Extension
{
    /// <summary>
    /// 扩展Prism框架的注册类型和初始化类型的功能
    /// </summary>
    public static class PrsimExtension
    {
        public static void RegisterAssembly(this IContainerRegistry container,Assembly assembly)
        {
            var list = GetTypes(assembly);

            foreach (var item in list)
            {
                RegisterAssembly(container,item);
            }
        }

        public static void RegisterAssembly(IContainerRegistry container, Type type)
        {
            var list = GetExposedServices(type);

            foreach (var item in list)
            {
                if(item.Lifttime== Lifttime.Singleton)
                {
                    container.RegisterSingleton(type);//表示将HardwareManager的反射注册到IOC容器中
                }

                foreach (var IType in item.Types)
                {
                    if(item.Lifttime== Lifttime.Singleton)
                    {
                        container.RegisterSingleton(IType,type);//表示 以IHardwareManager接口 注册 HardwareManager
                    }
                    else if (item.Lifttime == Lifttime.Transient)
                    {
                        container.Register(IType, type);
                    }
                }
            }
        }

        private static IEnumerable<ExposedServiceAttribute> GetExposedServices(Type type)
        {
            var typeInfo = type.GetTypeInfo();
            return typeInfo.GetCustomAttributes<ExposedServiceAttribute>();
        }

        private static List<Type> GetTypes(Assembly assembly)
        {
            var list = assembly.GetTypes().Where(t => t != null && t.IsClass && !t.IsAbstract
            && t.CustomAttributes.Any(p => p.AttributeType == typeof(ExposedServiceAttribute))).ToList();
            return list;
        }




        //初始化程序集中所有标注了ExposedServiceAttribute的类，要求单例模式，而且自动加载

        public static void InitializeAssembly(this IContainerProvider container,Assembly assembly)
        {
            var list =GetTypes(assembly);
            foreach (var item in list)
            {
                InitializeAssembly(container, item);
            }
        }

        private static void InitializeAssembly(IContainerProvider container,Type type)
        {
            var list = GetExposedServices(type);
            foreach (var item in list)
            {
                if (item.Lifttime == Lifttime.Singleton && item.AutoInitialize)
                {
                    container.Resolve(type);
                }
            }
        }
    }
}
